﻿using KBEngine;
using UnityEngine;
using System; 
using System.IO;  
using System.Collections; 
using System.Collections.Generic;
using System.Linq;

// 主要是场景内各种表现
public class World : MonoBehaviour 
{
    public bool inWorld = false;
    // 单例地形
	private UnityEngine.GameObject terrain = null;
	public UnityEngine.GameObject terrainPerfab;
	
    // 单例玩家
	private UnityEngine.GameObject player = null;
	public UnityEngine.GameObject entityPerfab;
	public UnityEngine.GameObject avatarPerfab;
	
	void Awake() 
	 {
		DontDestroyOnLoad(transform.gameObject);
	 }
	 
	// Use this for initialization
	void Start () 
	{
		installEvents();
	}

    // 注册
	void installEvents()
	{
		// in world
		KBEngine.Event.registerOut("addSpaceGeometryMapping", this, "addSpaceGeometryMapping");
		KBEngine.Event.registerOut("onEnterWorld", this, "onEnterWorld");
		KBEngine.Event.registerOut("onLeaveWorld", this, "onLeaveWorld");
		KBEngine.Event.registerOut("set_position", this, "set_position");
		KBEngine.Event.registerOut("set_direction", this, "set_direction");
		KBEngine.Event.registerOut("updatePosition", this, "updatePosition");
		KBEngine.Event.registerOut("onControlled", this, "onControlled");
		
		// in world(register by scripts)
		KBEngine.Event.registerOut("onAvatarEnterWorld", this, "onAvatarEnterWorld");
		KBEngine.Event.registerOut("set_HP", this, "set_HP");
		KBEngine.Event.registerOut("set_MP", this, "set_MP");
		KBEngine.Event.registerOut("set_HP_Max", this, "set_HP_Max");
		KBEngine.Event.registerOut("set_MP_Max", this, "set_MP_Max");
		KBEngine.Event.registerOut("set_name", this, "set_entityName");
		KBEngine.Event.registerOut("set_state", this, "set_state");
		KBEngine.Event.registerOut("set_moveSpeed", this, "set_moveSpeed");
		KBEngine.Event.registerOut("set_modelScale", this, "set_modelScale");
		KBEngine.Event.registerOut("set_modelID", this, "set_modelID");
		KBEngine.Event.registerOut("recvDamage", this, "recvDamage");
		KBEngine.Event.registerOut("otherAvatarOnJump", this, "otherAvatarOnJump");
		KBEngine.Event.registerOut("onAddSkill", this, "onAddSkill");
	}

	void OnDestroy()
	{
		KBEngine.Event.deregisterOut(this);
	}
	
	// Update is called once per frame
	void Update () 
	{
        if(inWorld == true)
        {
            // 尝试创建玩家
            createPlayer();

            // 尝试触发“跳”动作
            if (Input.GetKeyUp(KeyCode.Space))
            {
                Debug.Log("KeyCode.Space");
                KBEngine.Event.fireIn("jump");
            }
            // 尝试触发“攻击”动作
            else if (Input.GetMouseButton(0))
            {
                // 射线选择，攻击
                if (Camera.main)
                {
                    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                    RaycastHit hit;

                    if (Physics.Raycast(ray, out hit))
                    {
                        Debug.DrawLine(ray.origin, hit.point);
                        UnityEngine.GameObject gameObj = hit.collider.gameObject;
                        if (gameObj.name.IndexOf("terrain") == -1)
                        {
                            // 根据被攻击的游戏对象名称 最后一段为标识符
                            string[] s = gameObj.name.Split(new char[] { '_' });

                            if (s.Length > 0)
                            {
                                int targetEntityID = Convert.ToInt32(s[s.Length - 1]);
                                // 使用技能1来攻击对方
                                KBEngine.Event.fireIn("useTargetSkill", (Int32)1, (Int32)targetEntityID);
                            }
                        }
                    }
                }
            }
        }
        else
        {
            // 尝试移除玩家
            removePlayer();
        }
	}

    // 由服务端控制加载哪个场景数据(废弃)
    public void addSpaceGeometryMapping(string respath)
    {
        //Debug.Log("loading scene(" + respath + ")...");
        //UI.inst.info("scene(" + respath + "), spaceID=" + KBEngineApp.app.spaceID);
        //if (terrain == null)
        //    terrain = Instantiate(terrainPerfab) as UnityEngine.GameObject;

        //// 若存在玩家，也把玩家激活
        //if (player)
        //    player.GetComponent<GameEntity>().entityEnable();
    }

    public void createTerrain()
    {
        // 这里根据KBEngineApp.app.spaceID 来加载对应地形
        UI.inst.info(" spaceID =" + KBEngineApp.app.spaceID);
        if (terrain == null)
            terrain = Instantiate(terrainPerfab) as UnityEngine.GameObject;

        // 若存在玩家，也把玩家激活
        if (player)
            player.GetComponent<GameEntity>().entityEnable();
    }

    // 当玩家进入场景
    public void onAvatarEnterWorld(UInt64 rndUUID, Int32 eid, KBEngine.Avatar avatar)
	{
		if(!avatar.isPlayer())
		{
			return;
		}

		UI.inst.info("loading scene...(加载场景中...)");
		Debug.Log("loading scene...");
	}

    public void createPlayer()
    {
        // 在地形激活后再激活玩家
        if (player != null)
        {
            if (terrain == null)
            {
                createTerrain();
            }
            return;
        }

        // 当前控制实体类型为 Avatar 玩家
        if (KBEngineApp.app.entity_type != "Avatar")
        {
            return;
        }

        // 获取实体集中的玩家id对应的实体
        KBEngine.Avatar avatar = (KBEngine.Avatar)KBEngineApp.app.player();
        if (avatar == null)
        {
            Debug.Log("wait create(palyer)!");
            return;
        }

        // 防止陷入地下
        float y = avatar.position.y;
        if (avatar.isOnGround)
            y = 1.3f;

        // 创建当前玩家游戏对象
        player = Instantiate(avatarPerfab, new Vector3(avatar.position.x, y, avatar.position.z),
                             Quaternion.Euler(new Vector3(avatar.direction.y, avatar.direction.z, avatar.direction.x))) as UnityEngine.GameObject;

        // 默认不激活，等待地形生成
        player.GetComponent<GameEntity>().entityDisable();

        // 将来自服务端的实体与客户端的游戏对象绑定
        avatar.renderObj = player;

        // 设置该游戏对象为玩家
        ((UnityEngine.GameObject)avatar.renderObj).GetComponent<GameEntity>().isPlayer = true;

        // 有必要设置一下，由于该接口由Update异步调用，有可能set_position等初始化信息已经先触发了
        // 那么如果不设置renderObj的位置和方向将为0，人物会陷入地下
        set_position(avatar);
        set_direction(avatar);
    }

    public void removePlayer()
    {
        // 先取消激活玩家，再取消地形
        if (player == null)
        {
            if (terrain != null)
            {
                UI.inst.info(" spaceID = 大厅");
                Destroy(terrain);
                terrain = null;
            }
            return;
        }

        // 当前控制实体类型为 Avatar 玩家时就不处理
        if (KBEngineApp.app.entity_type == "Avatar")
        {
            return;
        }

        // 获取实体集中的玩家id对应的实体
        KBEngine.Avatar avatar = (KBEngine.Avatar)KBEngineApp.app.player();
        if (avatar != null)
        {
            Debug.Log("wait remove(palyer)!"); // 等待服务器真正移除角色
            return;
        }

        // 移除当前玩家游戏对象
        player.GetComponent<GameEntity>().entityDisable();
        Destroy(player);
        player = null;

        // 解除服务端的实体与客户端的游戏对象绑定
        avatar.renderObj = null;
    }

    // 响应学习技能
    public void onAddSkill(KBEngine.Entity entity)
	{
		Debug.Log("onAddSkill");
	}
	
    // 其他实体进入世界
	public void onEnterWorld(KBEngine.Entity entity)
	{
		if(entity.isPlayer())
			return;
		
		float y = entity.position.y;
		if(entity.isOnGround)
			y = 1.3f;
		
		entity.renderObj = Instantiate(entityPerfab, new Vector3(entity.position.x, y, entity.position.z), 
			Quaternion.Euler(new Vector3(entity.direction.y, entity.direction.z, entity.direction.x))) as UnityEngine.GameObject;

        // 类名+id
		((UnityEngine.GameObject)entity.renderObj).name = entity.className + "_" + entity.id;
	}
	
    // 实体离开世界
	public void onLeaveWorld(KBEngine.Entity entity)
	{
		if(entity.renderObj == null)
			return;
		
		UnityEngine.GameObject.Destroy((UnityEngine.GameObject)entity.renderObj);
		entity.renderObj = null;
	}

    // 将实体的位置 与 游戏对象位置 对应
    public void set_position(KBEngine.Entity entity)
	{
		if(entity.renderObj == null)
			return;

		GameEntity gameEntity = ((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>();
		gameEntity.destPosition = entity.position;
		gameEntity.position = entity.position;
        // 设置当前场景id
		gameEntity.spaceID = KBEngineApp.app.spaceID;
	}

    // 将实体的位置 与 游戏对象位置 更新（可以添加自己的操作）
    public void updatePosition(KBEngine.Entity entity)
	{
		if(entity.renderObj == null)
			return;

        GameEntity gameEntity = ((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>();
		gameEntity.destPosition = entity.position;
		gameEntity.isOnGround = entity.isOnGround;
        // 设置当前场景id
        gameEntity.spaceID = KBEngineApp.app.spaceID;
	}
	
    // 响应某个实体被玩家控制或者不控制
	public void onControlled(KBEngine.Entity entity, bool isControlled)
	{
		if(entity.renderObj == null)
			return;
		
		GameEntity gameEntity = ((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>();
		gameEntity.isControlled = isControlled;
	}
	
    // 设置实体方向
	public void set_direction(KBEngine.Entity entity)
	{
		if(entity.renderObj == null)
			return;
		
		GameEntity gameEntity = ((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>();
		gameEntity.destDirection = new Vector3(entity.direction.y, entity.direction.z, entity.direction.x);
        // 设置当前场景id
        gameEntity.spaceID = KBEngineApp.app.spaceID;
	}

    // 修改hp
	public void set_HP(KBEngine.Entity entity, Int32 v, Int32 HP_Max)
	{
		if(entity.renderObj != null)
		{
			((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>().hp = "" + v + "/" + HP_Max;
		}
	}
	
    // 修改mp
	public void set_MP(KBEngine.Entity entity, Int32 v, Int32 MP_Max)
	{
	}
	
    // 修改hp最大值
	public void set_HP_Max(KBEngine.Entity entity, Int32 v, Int32 HP)
	{
		if(entity.renderObj != null)
		{
			((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>().hp = HP + "/" + v;
		}
	}
	
    // 修改mp最大值
	public void set_MP_Max(KBEngine.Entity entity, Int32 v, Int32 MP)
	{
	}
	
    // 修改实体名称
	public void set_entityName(KBEngine.Entity entity, string v)
	{
		if(entity.renderObj != null)
		{
			((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>().entity_name = v;
		}
	}
	
    // 设置实体状态值
	public void set_state(KBEngine.Entity entity, SByte v)
	{
		if(entity.renderObj != null)
		{
			((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>().set_state(v);
		}
		
		if(entity.isPlayer())
		{
			Debug.Log("player->set_state: " + v);
			
            // 是否显示“复活”UI
			if(v == 1)
				UI.inst.showReliveGUI = true;
			else
				UI.inst.showReliveGUI = false;
			
			return;
		}
	}

    // 设置移动速度
	public void set_moveSpeed(KBEngine.Entity entity, Byte v)
	{
		float fspeed = ((float)(Byte)v) / 10f;
		
		if(entity.renderObj != null)
		{
			((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>().speed = fspeed;
		}
	}
	
    // 设置模型大小
	public void set_modelScale(KBEngine.Entity entity, Byte v)
	{
	}
	
    // 设置模型id
	public void set_modelID(KBEngine.Entity entity, UInt32 v)
	{
	}
	
    // 受到伤害
	public void recvDamage(KBEngine.Entity entity, KBEngine.Entity attacker, Int32 skillID, Int32 damageType, Int32 damage)
	{
	}
	
    // 其他玩家 进行“跳动作”
	public void otherAvatarOnJump(KBEngine.Entity entity)
	{
		Debug.Log("otherAvatarOnJump: " + entity.id);
		if(entity.renderObj != null)
		{
			((UnityEngine.GameObject)entity.renderObj).GetComponent<GameEntity>().OnJump();
		}
	}
}
